package com.baselib.libnetwork.net.libnetworkcomponent;

import android.text.TextUtils;

import com.baselib.libnetwork.net.HttpManager;
import com.baselib.libnetwork.net.request.CustomRequest;
import com.baselib.libnetwork.net.request.FileRequest;
import com.baselib.libnetwork.net.request.PostRequest;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import okhttp3.Response;

/**
 * @author lixuce
 * @version v1.0
 * @description 此类下的所有方法不能被直接只掉调用，调用者需自己写此类的继承者，在此类继承者上调用
 * @since 2018/1/23
 */

public abstract class BaseRequest {
    private StringBuffer stringBuffer = new StringBuffer();

    public void post(String url, String keyParams, String valueParams, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        CustomRequest request = appendRequest(true, HttpMethod.POST, url, null, null);
        request.params(keyParams, valueParams);

        asynExecute(request, callback);
    }

    public void post(String url, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        CustomRequest request = appendRequest(true, HttpMethod.POST, url, null, null);
        asynExecute(request, callback);
    }

    public void post(String url, String keyParams, String valueParams, Object tag, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        CustomRequest request = appendRequest(true, HttpMethod.POST, url, null, tag);
        request.params(keyParams, valueParams);

        asynExecute(request, callback);
    }


    private String appStr(String url) {

        if (url == null || url.isEmpty()) {
            return "";
        }

        if (stringBuffer.length() > 0) {
            stringBuffer.setLength(0);
        }

        stringBuffer.append(url.replace(" ", "").trim()).append("?");

        Map<String, String> commonParam = setCommonParam();
        if (commonParam != null && commonParam.size() > 0) {
            for (Map.Entry<String, String> entry : commonParam.entrySet()) {
                stringBuffer.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }

            String commonUrl = stringBuffer.toString();
            if (commonUrl.endsWith("&")) {
                commonUrl = commonUrl.substring(0, commonUrl.length() - 1);
            }
            return commonUrl;
        }

        return stringBuffer.toString();
    }

    protected abstract Map<String, String> setCommonParam();


    public void post(String url, Map<String, String> map, HttpCallback callback) {
        asynExecute(appendRequest(true, HttpMethod.POST, url, map, null), callback);
    }

    public void post(String url, Map<String, String> map, Object tag, HttpCallback callback) {
        asynExecute(appendRequest(true, HttpMethod.POST, url, map, tag), callback);
    }

    //TODO 表单
    private void formSend() {

    }

    /**
     * @param conCom 是否包含公参
     * @param method 请求方法
     * @param url    请求地址
     * @param map    请求参数
     * @param tag    请求标签
     * @return
     */
    private CustomRequest appendRequest(boolean conCom, HttpMethod method,
                                        String url, Map<String, String> map, Object tag) {
        CustomRequest request;
        if (conCom) {
            request = method == HttpMethod.GET ?
                    HttpManager.get(appStr(url)) : HttpManager.post(appStr(url));
        } else {
            request = method == HttpMethod.GET ?
                    HttpManager.get(url) : HttpManager.post(url);
        }
        if (map != null && map.size() > 0) {
            request.params(map);
        }
        if (tag != null) {
            request.tag(tag);
        }
        return request;
    }


    /**
     * 目前只接受两个类型的参数   String 和 file
     */
    public FileRequest fileRequest(String url, Map<String, Object> map) {
        FileRequest request = HttpManager.post(appStr(url));
        if (map != null && map.size() > 0) {
//            request.params(map);
            Iterator<String> iterator = map.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                Object value = map.get(key);
                if (value instanceof File) {
                    request.params(key, (File) value);
                } else {
                    request.params(key, (String) value);
                }
            }
        }
        return request;
    }

    /**
     * 目前只接受两个类型的参数   String 和 file
     * 添加标记  取消网络请求时使用
     */
    public FileRequest fileRequest(String url, Map<String, Object> map, Object tag) {
        FileRequest fileRequest = fileRequest(url, map);
        fileRequest.tag(tag);
        return fileRequest;
    }

    //上传文件
    public void postFile(String url, Map<String, Object> map, HttpCallback callback) {
        asynExecute(fileRequest(url, map), callback);
    }

    /**
     * 上传文件
     *
     * @param url        地址
     * @param map        参数
     * @param callback   回调
     * @param tag        通过tag  可以取消网络请求   i
     * @param isNullData 文件是否为  null    带文件上传没有携带文件的时候使用
     */
    public void postFile(String url, Map<String, Object> map, HttpCallback callback, Object tag, boolean isNullData) {
        FileRequest fileRequest = fileRequest(url, map, tag);
        fileRequest.setNullFile(isNullData);
        asynExecute(fileRequest, callback);
    }

    public void postFile(String url, Map<String, Object> map, HttpCallback callback, Object tag, File file) {
        FileRequest fileRequest = fileRequest(url, map, tag);
        fileRequest.setNullFile(false);
        fileRequest.upFile(file);
        asynExecute(fileRequest, callback);
    }

    private enum HttpMethod {
        GET(0), POST(1);
        int method;

        HttpMethod(int method) {
            this.method = method;
        }

        public int getMethod() {
            return method;
        }

        public void setMethod(int method) {
            this.method = method;
        }
    }

    /**
     * GET
     *
     * @param url
     * @param callback
     */
    public void get(String url, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        asynExecute(appendRequest(true, HttpMethod.GET, url, null, null), callback);
    }

    /**
     * GET
     *
     * @param url
     * @param tag
     * @param callback
     */
    public void get(String url, Object tag, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        asynExecute(appendRequest(true, HttpMethod.GET, url, null, tag), callback);
    }

    /**
     * GET 单参
     *
     * @param url
     * @param paramsKey
     * @param paramsValue
     * @param callback
     */
    public void get(String url, String paramsKey, String paramsValue, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        Map<String, String> map = new HashMap<>();
        map.put(paramsKey, paramsValue);
        CustomRequest get = appendRequest(true, HttpMethod.GET, url, map, null);
        asynExecute(get, callback);
    }

    /**
     * GET 单参
     *
     * @param url
     * @param paramsKey
     * @param paramsValue
     * @param callback
     */
    public void get(String url, String paramsKey, String paramsValue, Object tag, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        Map<String, String> map = new HashMap<>();
        map.put(paramsKey, paramsValue);
        CustomRequest get = appendRequest(true, HttpMethod.GET, url, map, tag);
        asynExecute(get, callback);
    }

    /**
     * GET
     *
     * @param url
     * @param map
     * @param callback
     */
    public void get(String url, Map<String, String> map, Object tag, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        asynExecute(appendRequest(true, HttpMethod.GET, url, map, tag), callback);
    }


    /**
     * GET
     *
     * @param url
     * @param map
     * @param callback
     */
    public void get(String url, Map<String, String> map, HttpCallback callback) {
        if (TextUtils.isEmpty(url)) {
            return;
        }
        asynExecute(appendRequest(true, HttpMethod.GET, url, map, null), callback);
    }


    public void postNoCommon(String url, Map<String, String> map, HttpCallback callback) {
        CustomRequest request = appendRequest(false, HttpMethod.POST, url, null, null);
        request.params(map);
        asynExecute(request, callback);
    }

    public void getNoCommon(String url, Map<String, String> map, HttpCallback callback) {
        CustomRequest request = appendRequest(false, HttpMethod.GET, url, null, null);
        request.params(map);
        asynExecute(request, callback);
    }

    private void asynExecute(CustomRequest customRequest, HttpCallback callback) {
        customRequest.execute(callback);
    }


    public Response execute(CustomRequest customRequest) throws IOException {
        return customRequest.execute();
    }

    public void cancel(Object tag) {
        HttpManager.getInstance().cancelTag(tag);
    }

    public void postBodyJson(boolean conCom, String url, Map<String, String> map, String json, HttpCallback callback) {
        PostRequest postRequest = HttpManager.post(conCom ? appStr(url) : url);
        postRequest.upJson(json);
        asynExecute(postRequest, callback);
    }

}
